<?php

/**
 * 
 * @desc 系统框架资源调度器
 * 
 * @author keluo <pycorvn@yeah.net>
 * @since 2011-5-22 20:29:18
 * @link http://www.scabish.cn/framework
 */
class SCScabish {
	
	private static $_instance;
	
	private function __construct() {}
	
	public static function getInstance() {
		if(!(self::$_instance instanceof self)) {
			self::$_instance = new self();
		}
	}
	
	public function __clone() {}
	
	/**
	 * 运行框架
	 * @throws Exception
	 */
	public static function run() {
		date_default_timezone_set('PRC');
		SCRequest::init();
		
		$controllerName = SCRequest::getControllerName();
		try {
			$rc = new ReflectionClass($controllerName.'Controller');
		} catch (Exception $e) {
			try {
				$rc = new ReflectionClass('EmptyController'); 
			} catch (Exception $e) {
				trigger_error('undefined controller: '.$controllerName, E_USER_ERROR);
			}
		}
		if(!$rc->isSubclassOf('SCController')) {
			trigger_error('undefined controller', E_USER_ERROR);
		}
		$actionName = SCRequest::getActionName();
		if(!$rc->hasMethod($actionName)) {
			if(!$rc->hasMethod('__empty')) {
				trigger_error('undefined method: '.$actionName, E_USER_ERROR);	
			} else {
				$actionName = '__empty';
			}
		}
		$controller = $rc->newInstance();
		
		$method = $rc->getMethod($actionName);
		$params = self::checkMethod($method);
		$method->invokeArgs($controller, $params);
		
		SCFatal::$clean = true;
	}
	
	/**
	 * 加载自定义组件类
	 */
	public static function helper($class) {
		
	}
	
	/**
	 * 加载模型类
	 * @param string $class 模型类名(无Model后缀)
	 * @param boolean cached 是否缓存对象
	 * @return object
	 * @example SCScabish::model('user')->getLoginInfo()
	 */
	public static function model($class = '', $cached = true) {
		if($class == '') $class = 'SC';
		$class = $class.'Model';
		static $loaded = array();
		
		if($cached && !array_key_exists($class, $loaded)) {
			$loaded[$class] = new $class;
		}
		
		return $loaded[$class];
	}
	
	/**
	 * 加载核心组件类
	 * @param string $class 类名(无SC前缀)
	 * @param boolean cached 是否缓存对象
	 * @return object
	 * @example SCScabish::core('url')->create('blog/index')
	 */
	public static function core($class, $cached = true) {
		$class = 'SC'.$class;
		static $loaded = array();
		if($cached && !array_key_exists($class, $loaded)) {
			$loaded[$class] = new $class;
		}
		
		return $loaded[$class];
	}
	
	/**
	 * 检查方法所需参数
	 * @param object $method
	 * @return array 参数结果集
	 */
	protected static function checkMethod($method) {
		$params = $method->getParameters();
		if(empty($params)) return array();
		$values = array();
		foreach($params as $param) {
			if($param->isDefaultValueAvailable()) {
				if(false === SCRequest::request($param->getName())) continue;
				$values[] = SCRequest::request($param->getName());
			} else {
				if(!array_key_exists($param->getName(), SCRequest::request())) {
					trigger_error('param of $'.$param->getName().' is required in action '.$method->name, E_USER_ERROR);
				}
				$values[] = SCRequest::request($param->getName());
			}
		}
		return $values;
	}
	
}